#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <vector>
#include "gc_ptr.h"
#include "go.h"
#include "taginfo.h"
#include <list>
#include "boxing2.h"



struct llist
{
	int val;
	gc_ptr<llist> next;

	llist ()
	{
		val = 0;
		next = 0;
	}

	llist (int v)
	{
		val = v;
		next = 0;
	}
};

void add (gc_ptr<llist> &head, gc_ptr<llist> elem, gc_ptr<llist> cur)
{
//	printf ("%p %p %p\n", &head, &elem, &cur);
	if (head == 0)
	{
		head = elem;
		return;
	}
	if (cur->next == NULL)
	{
		cur->next = elem;
	}
	else 
		add (head, elem, cur->next);
}

void print (gc_ptr<llist> cur)
{
	if (cur == 0)
		return;
	printf("%d\n", (*cur).val);
	print(cur->next);
}

std::vector <void *> v;
std::map <void *, void*> mm;


void test (int STEP_COUNT, int ELEM_COUNT)
{
	std::list <size_t> llist1;
	llist1.push_front(64);
	for (int i = 0; i < STEP_COUNT; i++)
	{
		gc_ptr<llist> head;
		printf ("%p\n", &head);
		head = 0;
		for (int j = 0; j < ELEM_COUNT; j++)
		{
			printf ("j = %d\n", j);
			gc_ptr<llist> nw; 
//			printf ("%p\n", &nw);
			nw = new llist(j);
//			printf ("!!!\n");
			void *tmp = nw.ptr;
//			tmp = tmp - sizeof(void *);
			void*tmp2;
			mm[tmp] = tmp2 = generic_box_struct(llist1);
			v.push_back (mm[tmp]);
//			printf ("add begin\n");
			add(head, nw, head);
//			printf ("add end\n");
//			printf ("obj = %p\n", nw.ptr);
//     			printf ("gen_return = %p\n", tmp2);
		}

//		print(head);

//		printf ("head = %p\n", &head);

		for (ptr_list *l = collect(); l != 0; l = l->next)
		{
			printf ("root = %p\n", l->ptr);
			go (reinterpret_cast <void*> (*((long *)(l->ptr))), 1);
//			go(l->ptr, 1);
		}

		for (size_t i = 0; i < v.size(); i++)
			assert ((*((BLOCK_TAG *)v[i])).mbit == 1);	  

	}

	

}

int main (int argc, char *argv[])
{
	assert(argc == 3);
	int STEP_COUNT, ELEM_COUNT;
	sscanf (argv[1], "%d", &STEP_COUNT);
	sscanf (argv[2], "%d", &ELEM_COUNT);

	test(STEP_COUNT, ELEM_COUNT);

	return 0;
}
